#include "glchildfractal.h"

GLChildFractal::GLChildFractal()
    : GLChild()
{
    setAttribute(Qt::WA_DeleteOnClose);

    timer = new QTimer(this);
}

GLChildFractal::~GLChildFractal()
{
    if (fractal)
    {
        delete fractal;
        fractal = NULL;
    }

    if (timer)
    {
        delete timer;
    }
}

void GLChildFractal::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();

    ViewAll();

    // setup viewpoint from current arcball
    arcball.glDraw();

    fractal->draw();

    glPopMatrix();

    glFlush();
    glFinish();
}

void GLChildFractal::resetView()
{
    arcball.Clear();

    arcball.SetCenter(0, 0, 0);

    ViewAll(false);

    repaint();
}

void GLChildFractal::generate()
{
    Point pt(0, 0);
    Box box(-20, 20, -20, 20);

    fractal = new Koch(box, pt, 10, 3);

    fractal->start();

    connect(timer, SIGNAL(timeout()), this, SLOT(repaint()));
    timeStart = clock();
    timer->start(1000);
}

void GLChildFractal::ViewAll(bool check_first)
{
    // make it only once
    if(!m_FirstView && check_first)
        return;

    m_FirstView = false;

    // set up the camera to visualize the whole object
    //	TRACE("setup camera.");

    CMatrix44 ArcballMatrix = arcball.GetMatrix();

    CVector3d minBound, maxBound;
    minBound.Set(-30, -30, -5);
    maxBound.Set(30, 30, 5);
    minBound = ArcballMatrix * minBound;
    maxBound = ArcballMatrix * maxBound;
    camera.ViewAll(minBound[0],
        maxBound[0],
        minBound[1],
        maxBound[1],
        minBound[2],
        maxBound[2],
        viewport);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    camera.glDraw(viewport);
    glMatrixMode(GL_MODELVIEW);
}
